package com.gnerv.rabbitmq.manage.handler;

import com.gnerv.rabbitmq.manage.tool.StringTools;
import com.gnerv.rabbitmq.manage.model.ExecResult;
import com.jcraft.jsch.*;
import lombok.Data;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author ligen
 */
@Data
public class ExecHandler {

    private static final JSch JSCH = new JSch();

    private String host;
    private int port;
    private String username;
    private String password;

    private Session session;
    private ChannelExec channel;

    // 3. 获取标准输入流
    BufferedReader inputStreamReader;
    // 4. 获取标准错误输入流
    BufferedReader errInputStreamReader;


    public final ExecResult handle(String command) {
        try {
            return executeCommand(command);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public final void connect() {
        createSession();
    }

    public final void disconnect() {
        channel.disconnect();
        session.disconnect();
    }

    private void createSession() {
        try {
            session = JSCH.getSession(username, host, port);
            session.setPassword(password);
            session.setConfig("StrictHostKeyChecking", "no");
            session.setTimeout(3000);
            session.connect();
        } catch (JSchException e) {
            throw new RuntimeException(e);
        }
    }

    private ExecResult executeCommand(String command) throws IOException {
        ExecResult execResult = new ExecResult();
        try {
            channel = (ChannelExec) session.openChannel("exec");
            channel.setCommand(command);
            channel.connect(3000);
            inputStreamReader = new BufferedReader(new InputStreamReader(channel.getInputStream()));
            errInputStreamReader = new BufferedReader(new InputStreamReader(channel.getErrStream()));
            execResult.setStdout(readStream(inputStreamReader));
            execResult.setStderr(readStream(errInputStreamReader));
            while (true) {
                if (channel.isClosed()) {
                    int exitStatus = channel.getExitStatus();
                    execResult.setStatus(exitStatus);
                    break;
                }
            }
        } catch (JSchException e) {
            throw new RuntimeException(e);
        }
        return execResult;
    }

    private static String readStream(BufferedReader bufferedReader) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            stringBuilder.append(line).append("\n");
        }
        String builderString = stringBuilder.toString();
        return StringTools.removeColorCharacters(builderString);
    }


}
